home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part2 / 17091 < prev    next >
Encoding:
Text File  |  1996-08-05  |  36.0 KB  |  924 lines

  1. Path: sun.soe.clarkson.edu!cline
  2. From: cline@sun.soe.clarkson.edu (Marshall Cline)
  3. Newsgroups: comp.lang.c++
  4. Subject: C++ FAQ: posting #4/4
  5. Followup-To: comp.lang.c++
  6. Date: 13 Apr 1996 17:41:36 GMT
  7. Organization: Paradigm Shift, Inc (technology consulting)
  8. Sender: cline@sun.soe.clarkson.edu
  9. Distribution: world
  10. Expires: +1 month
  11. Message-ID: <4kop0g$l61@library.erc.clarkson.edu>
  12. Reply-To: cline@parashift.com (Marshall Cline)
  13. NNTP-Posting-Host: sun.soe.clarkson.edu
  14. Summary: Please read this before posting to comp.lang.c++
  15. Archive-name: C++-faq/part4_4
  16.  
  17. comp.lang.c++ Frequently Asked Questions list (with answers, fortunately).
  18. Copyright (C) 1991-96 Marshall P. Cline, Ph.D.
  19. Posting 4 of 4.
  20. Posting #1 explains copying permissions, (no)warranty, table-of-contents, etc
  21.  
  22. ==============================================================================
  23. SECTION 17: Linkage-to/relationship-with C
  24. ==============================================================================
  25.  
  26. Q111: How can I call a C function "f(int,char,float)" from C++ code?
  27.  
  28. Tell the C++ compiler that it is a C function:
  29.     extern "C" void f(int,char,float);
  30.  
  31. Be sure to include the full function prototype.  A block of many C functions
  32. can be grouped via braces, as in:
  33.  
  34.     extern "C" {
  35.       void* malloc(size_t);
  36.       char* strcpy(char* dest, const char* src);
  37.       int   printf(const char* fmt, ...);
  38.     }
  39.  
  40. ==============================================================================
  41.  
  42. Q112: How can I include a C header file in my C++ code?
  43.  
  44. If it's a standard header file, you don't have to do anything unusual.  E.g.,
  45.  
  46.     #include <stdio.h>
  47.  
  48. If it's not one of the system-provided standard header files, you may need to
  49. wrap the '#include' line in an 'extern "C" {...}' construct (but please note
  50. that this is not necessary for the standard header files such as '<stdio.h>'):
  51.  
  52.     extern "C" {
  53.       #include "my-C-code.h"
  54.     }
  55.  
  56. Note: If you have the ability to change the .h file, please see the next FAQ.
  57.  
  58. ==============================================================================
  59.  
  60. Q113: How can I modify a C header file so it can be #included in C++ code?
  61.  
  62. If the C header file is a standard header (e.g., 'stdio.h'), you don't have to
  63. do anything; see two FAQs back.  If you can't change the header file (e.g., if
  64. you don't have write access to the file), see the previous FAQ.
  65.  
  66. If you are able to change the C header file, you should strongly consider
  67. adding the 'extern "C" {...}' logic inside the header file to make it easier
  68. for C++ users to #include it into their C++ code.  Naturally you must wrap the
  69. 'extern "C" {' and '}' lines in an '#ifdef' so they won't be seen by normal C
  70. compilers.
  71.  
  72. Step #1: put the following lines at the very top of your C header file:
  73.  
  74.     #ifdef __cplusplus
  75.     extern "C" {
  76.     #endif
  77.  
  78. Step #2: put the following lines at the very bottom of your C header file:
  79.  
  80.     #ifdef __cplusplus
  81.     }
  82.     #endif
  83.  
  84. ==============================================================================
  85.  
  86. Q114: How can I create a C++ function "f(int,char,float)" that is callable by
  87.    my C code?
  88.  
  89. The C++ compiler must know that "f(int,char,float)" is to be called by a C
  90. compiler using the same "extern C" construct detailed in the previous FAQ.
  91. Then you define the function in your C++ module:
  92.  
  93.     extern "C" void f(int,char,float);
  94.  
  95.     //...
  96.  
  97.     void f(int x, char y, float z)
  98.     {
  99.       //...
  100.     }
  101.  
  102. The "extern C" line tells the compiler that the external information sent to
  103. the linker should use C calling conventions and name mangling (e.g., preceded
  104. by a single underscore).  Since name overloading isn't supported by C, you
  105. can't make several overloaded fns simultaneously callable by a C program.
  106.  
  107. Caveats and implementation dependencies:
  108.  * your "main()" should be compiled with your C++ compiler (for static init).
  109.  * your C++ compiler should direct the linking process (for special libraries).
  110.  * your C and C++ compilers may need to come from same vendor and have
  111.    compatible versions (i.e., needs same calling convention, etc.).
  112.  
  113. ==============================================================================
  114.  
  115. Q115: Why's the linker giving errors for C/C++ fns being called from C++/C
  116.    fns?
  117.  
  118. See the previous two FAQs on how to use "extern "C"."
  119.  
  120. ==============================================================================
  121.  
  122. Q116: How can I pass an object of a C++ class to/from a C function?
  123.  
  124. Here's an example:
  125.  
  126.     /****** C/C++ header file: Fred.h ******/
  127.     #ifdef __cplusplus    /*"__cplusplus" is #defined if/only-if compiler is C++*/
  128.       extern "C" {
  129.     #endif
  130.  
  131.     #ifdef __STDC__
  132.       extern void c_fn(struct Fred*);    /* ANSI-C prototypes */
  133.       extern struct Fred* cplusplus_callback_fn(struct Fred*);
  134.     #else
  135.       extern void c_fn();            /* K&R style */
  136.       extern struct Fred* cplusplus_callback_fn();
  137.     #endif
  138.  
  139.     #ifdef __cplusplus
  140.       }
  141.     #endif
  142.  
  143.     #ifdef __cplusplus
  144.       class Fred {
  145.       public:
  146.         Fred();
  147.         void wilma(int);
  148.       private:
  149.         int a_;
  150.       };
  151.     #endif
  152.  
  153. "Fred.C" would be a C++ module:
  154.  
  155.     #include "Fred.h"
  156.     Fred::Fred() : a_(0) { }
  157.     void Fred::wilma(int a) { }
  158.  
  159.     Fred* cplusplus_callback_fn(Fred* fred)
  160.     {
  161.       fred->wilma(123);
  162.       return fred;
  163.     }
  164.  
  165. "main.C" would be a C++ module:
  166.  
  167.     #include "Fred.h"
  168.  
  169.     int main()
  170.     {
  171.       Fred fred;
  172.       c_fn(&fred);
  173.       return 0;
  174.     }
  175.  
  176. "c-fn.c" would be a C module:
  177.  
  178.     #include "Fred.h"
  179.     void c_fn(struct Fred* fred)
  180.     {
  181.       cplusplus_callback_fn(fred);
  182.     }
  183.  
  184. Passing ptrs to C++ objects to/from C fns will FAIL if you pass and get back
  185. something that isn't EXACTLY the same pointer.  For example, DON'T pass a base
  186. class ptr and receive back a derived class ptr, since your C compiler won't
  187. understand the pointer conversions necessary to handle multiple and/or virtual
  188. inheritance.
  189.  
  190. ==============================================================================
  191.  
  192. Q117: Can my C function access data in an object of a C++ class?
  193.  
  194. Sometimes.
  195.  
  196. (First read the previous FAQ on passing C++ objects to/from C functions.)
  197.  
  198. You can safely access a C++ object's data from a C function if the C++ class:
  199.  * has no virtual functions (including inherited virtual fns)
  200.  * has all its data in the same access-level section (private/protected/public)
  201.  * has no fully-contained subobjects with virtual fns
  202.  
  203. If the C++ class has any base classes at all (or if any fully contained
  204. subobjects have base classes), accessing the data will TECHNICALLY be
  205. non-portable, since class layout under inheritance isn't imposed by the
  206. language.  However in practice, all C++ compilers do it the same way: the base
  207. class object appears first (in left-to-right order in the event of multiple
  208. inheritance), and subobjects follow.
  209.  
  210. Furthermore, if the class (or any base class) contains any virtual functions,
  211. you can often (but less than always) assume a "void*" appears in the object
  212. either at the location of the first virtual function or as the first word in
  213. the object.  Again, this is not required by the language, but it is the way
  214. "everyone" does it.
  215.  
  216. If the class has any virtual base classes, it is even more complicated and less
  217. portable.  One common implementation technique is for objects to contain an
  218. object of the virtual base class (V) last (regardless of where "V" shows up as
  219. a virtual base class in the inheritance hierarchy).  The rest of the object's
  220. parts appear in the normal order.  Every derived class that has V as a virtual
  221. base class actually has a POINTER to the V part of the final object.
  222.  
  223. ==============================================================================
  224.  
  225. Q118: Why do I feel like I'm "further from the machine" in C++ as opposed to
  226.    C?
  227.  
  228. Because you are.
  229.  
  230. As an OOPL, C++ allows you to model the problem domain itself, which allows you
  231. to program in the language of the problem domain rather than in the language of
  232. the solution domain.
  233.  
  234. One of C's great strengths is the fact that it has "no hidden mechanism": what
  235. you see is what you get.  You can read a C program and "see" every clock cycle.
  236. This is not the case in C++; old line C programmers (such as many of us once
  237. were) are often ambivalent (can anyone say, "hostile") about this feature, but
  238. they soon realize that it provides a level of abstraction and economy of
  239. expression which lowers maintenance costs without destroying run-time
  240. performance.
  241.  
  242. Naturally you can write bad code in any language; C++ doesn't guarantee any
  243. particular level of quality, reusability, abstraction, or any other measure of
  244. "goodness."  C++ doesn't try to make it impossible for bad programmers to write
  245. bad programs; it enables reasonable developers to create superior software.
  246.  
  247. ==============================================================================
  248. SECTION 18: Pointers to member functions
  249. ==============================================================================
  250.  
  251. Q119: Is the type of "ptr-to-member-fn" different from "ptr-to-fn"?
  252.  
  253. Yep.
  254.  
  255. Consider the following function:
  256.  
  257.     int f(char a, float b);
  258.  
  259. If this is an ordinary function, its type is:    int (*)      (char,float);
  260. If this is a method of class Fred, its type is:  int (Fred::*)(char,float);
  261.  
  262. ==============================================================================
  263.  
  264. Q120: How do I pass a ptr to member fn to a signal handler, X event callback,
  265.    etc?
  266.  
  267. Don't.
  268.  
  269. Because a member function is meaningless without an object to invoke it on, you
  270. can't do this directly (if The X Windows System was rewritten in C++, it would
  271. probably pass references to OBJECTS around, not just pointers to fns; naturally
  272. the objects would embody the required function and probably a whole lot more).
  273.  
  274. As a patch for existing software, use a top-level (non-member) function as a
  275. wrapper which takes an object obtained through some other technique (held in a
  276. global, perhaps).  The top-level function would apply the desired member
  277. function against the global object.
  278.  
  279. E.g., suppose you want to call Fred::memfn() on interrupt:
  280.  
  281.     class Fred {
  282.     public:
  283.       void memfn();
  284.       static void staticmemfn();    //a static member fn can handle it
  285.       //...
  286.     };
  287.  
  288.     //wrapper fn remembers the object on which to invoke memfn in a global:
  289.     Fred* object_which_will_handle_signal;
  290.     void Fred_memfn_wrapper() { object_which_will_handle_signal->memfn(); }
  291.  
  292.     main()
  293.     {
  294.       /* signal(SIGINT, Fred::memfn); */   //Can NOT do this
  295.       signal(SIGINT, Fred_memfn_wrapper);  //Ok
  296.       signal(SIGINT, Fred::staticmemfn);   //Also Ok
  297.     }
  298.  
  299. Note: static member functions do not require an actual object to be invoked, so
  300. ptrs-to-static-member-fns are type compatible with regular ptrs-to-fns (see ARM
  301. ["Annotated Reference Manual"] p.25, 158).
  302.  
  303. ==============================================================================
  304.  
  305. Q121: Why do I keep getting compile errors (type mismatch) when I try to use a
  306.    member function as an interrupt service routine? 
  307.  
  308. This is a special case of the previous two questions, therefore read the
  309. previous two answers first.
  310.  
  311. Non-static member functions have a hidden parameter that corresponds to the
  312. 'this' pointer.  The 'this' pointer points to the instance data for the
  313. object.  The interrupt hardware/firmware in the system is not capable of
  314. providing the 'this' pointer argument.  You must use "normal" functions (non
  315. class members) or static member functions as interrupt service routines.
  316.  
  317. One possible solution is to use a static member as the interrupt service
  318. routine and have that function look somewhere to find the instance/member pair
  319. that should be called on interrupt.  Thus the effect is that a normal method
  320. is invoked on an interrupt, but for technical reasons you need to call an
  321. intermediate function first.
  322.  
  323. ==============================================================================
  324.  
  325. Q122: Why am I having trouble taking the address of a C++ function?
  326.  
  327. This is a corollary to the previous FAQ.
  328.  
  329. Long answer: In C++, member fns have an implicit parameter which points to the
  330. object (the "this" ptr inside the member fn).  Normal C fns can be thought of
  331. as having a different calling convention from member fns, so the types of their
  332. ptrs (ptr-to-member-fn vs ptr-to-fn) are different and incompatible.  C++
  333. introduces a new type of ptr, called a ptr-to-member, which can be invoked only
  334. by providing an object (see ARM ["Annotated Reference Manual"] 5.5).
  335.  
  336. NOTE: do NOT attempt to "cast" a ptr-to-mem-fn into a ptr-to-fn; the result is
  337. undefined and probably disastrous.  E.g., a ptr-to- member-fn is NOT required
  338. to contain the machine addr of the appropriate fn (see ARM, 8.1.2c, p.158).  As
  339. was said in the last example, if you have a ptr to a regular C fn, use either a
  340. top-level (non-member) fn, or a "static" (class) member fn.
  341.  
  342. ==============================================================================
  343.  
  344. Q123: How do I declare an array of pointers to member functions?
  345.  
  346. Keep your sanity with "typedef".
  347.  
  348.     class Fred {
  349.     public:
  350.       int f(char x, float y);
  351.       int g(char x, float y);
  352.       int h(char x, float y);
  353.       int i(char x, float y);
  354.       //...
  355.     };
  356.  
  357.     typedef  int (Fred::*FredPtr)(char x, float y);
  358.  
  359. Here's the array of pointers to member functions:
  360.  
  361.     FredPtr a[4] = { &Fred::f, &Fred::g, &Fred::h, &Fred::i };
  362.  
  363. To call one of the member functions on object "fred":
  364.  
  365.     void userCode(Fred& fred, int methodNum, char x, float y)
  366.     {
  367.       //assume "methodNum" is between 0 and 3 inclusive
  368.       (fred.*a[methodNum])(x, y);
  369.     }
  370.  
  371. You can make the call somewhat clearer using a #define:
  372.  
  373.     #define  callMethod(object,ptrToMethod)   ((object).*(ptrToMethod))
  374.     callMethod(fred, a[methodNum]) (x, y);
  375.  
  376. ==============================================================================
  377. SECTION 19: Container classes and templates
  378. ==============================================================================
  379.  
  380. Q124: How can I build a <favorite container> of objects of different types?
  381.  
  382. You can't, but you can fake it pretty well.  In C/C++ all arrays are
  383. homogeneous (i.e., the elements are all the same type).  However, with an extra
  384. layer of indirection you can give the appearance of a heterogeneous container
  385. (a heterogeneous container is a container where the contained objects are of
  386. different types).
  387.  
  388. There are two cases with heterogeneous containers.
  389.  
  390. The first case occurs when all objects you want to store in a container are
  391. publically derived from a common base class.  You can then declare/define your
  392. container to hold pointers to the base class.  You indirectly store a derived
  393. class object in a container by storing the object's address as an element in
  394. the container.  You can then access objects in the container indirectly through
  395. the pointers (enjoying polymorphic behavior).  If you need to know the exact
  396. type of the object in the container you can use 'dynamic_cast<>' or 'typeid()'.
  397. You'll probably need the virtual constructor (a.k.a. cloning) idiom to copy a
  398. container of disparate object types.  The downside of this approach is that it
  399. makes memory management a little more problematic (who "owns" the pointed-to
  400. objects? if you 'delete' these pointed-to objects when you destroy the
  401. container, how can you guarantee that no one else has a copy of one of these
  402. pointers? if you don't 'delete' these pointed-to objects when you destroy the
  403. container, how can you be sure that someone else will eventually do the
  404. 'delete'ing?).  It also makes copying the container more complex (may actually
  405. break the container's copying functions since you don't want to copy the
  406. pointers, at least not when the container "owns" the pointed-to objects).
  407.  
  408. The second case occurs when the object types are disjoint -- they do not share
  409. a common base class.  The approach here is to use a handle class.  The
  410. container is a container of handle objects (by value or by pointer, your
  411. choice; by value is easier).  Each handle object knows how to "hold on to"
  412. (i.e. ,maintain a pointer to) one of the objects you want to put in the
  413. container.  You can use either a single handle class with several different
  414. types of pointers as instance data, or a hierarchy of handle classes that
  415. shadow the various types you wish to contain (requires the container be of
  416. handle base clsss pointers).  The downside of this approach is that it opens up
  417. the handle class(es) to maintenance every time you change the set of types that
  418. can be contained.  The benefit is that you can use the handle class(es) to
  419. encapsulate most of the ugliness of memory management and object lifetime.
  420. Thus using handle objects may be beneficial even in the first case.
  421.  
  422. [Adapted with permission from an email from Phil Staite, pstaite@vnet.ibm.com].
  423.  
  424. ==============================================================================
  425.  
  426. Q125: How can I insert/access/change elements from a linked
  427.    list/hashtable/etc?
  428.  
  429. I'll use an "inserting into a linked list" as a prototypical example.  It's easy
  430. to allow insertion at the head and tail of the list, but limiting ourselves to
  431. these would produce a library that is too weak (a weak library is almost worse
  432. than no library).
  433.  
  434. This answer will be a lot to swallow for novice C++'ers, so I'll give a couple
  435. of options.  The first option is easiest; the second and third are better.
  436.  
  437. [1] Empower the "List" with a "current location," and methods such as
  438. advance(), backup(), atEnd(), atBegin(), getCurrElem(), setCurrElem(Elem),
  439. insertElem(Elem), and removeElem().  Although this works in small examples, the
  440. notion of "a" current position makes it difficult to access elements at two or
  441. more positions within the List (e.g., "for all pairs x,y do the following...").
  442.  
  443. [2] Remove the above methods from the List itself, and move them to a separate
  444. class, "ListPosition."  ListPosition would act as a "current position" within a
  445. List.  This allows multiple positions within the same List.  ListPosition would
  446. be a friend of List, so List can hide its innards from the outside world (else
  447. the innards of List would have to be publicized via public methods in List).
  448. Note: ListPosition can use operator overloading for things like advance() and
  449. backup(), since operator overloading is syntactic sugar for normal methods.
  450.  
  451. [3] Consider the entire iteration as an atomic event, and create a class
  452. template to embodies this event.  This enhances performance by allowing the
  453. public access methods (which may be virtual fns) to be avoided during the inner
  454. loop.  Unfortunately you get extra object code in the application, since
  455. templates gain speed by duplicating code.  For more, see [Koenig, "Templates as
  456. interfaces," JOOP, 4, 5 (Sept 91)], and [Stroustrup, "The C++ Programming
  457. Language Second Edition," under "Comparator"].
  458.  
  459. ==============================================================================
  460.  
  461. Q126: What's the idea behind "templates"?
  462.  
  463. A template is a cookie-cutter that specifies how to cut cookies that all look
  464. pretty much the same (although the cookies can be made of various kinds of
  465. dough, they'll all have the same basic shape).  In the same way, a class
  466. template is a cookie cutter to description of how to build a family of classes
  467. that all look basically the same, and a function template describes how to
  468. build a family of similar looking functions.
  469.  
  470. Class templates are often used to build type safe containers (although this
  471. only scratches the surface for how they can be used).
  472.  
  473. ==============================================================================
  474.  
  475. Q127: What's the syntax / semantics for a "function template"?
  476.  
  477. Consider this function that swaps its two integer arguments:
  478.  
  479.     void swap(int& x, int& y)
  480.     {
  481.       int tmp = x;
  482.       x = y;
  483.       y = tmp;
  484.     }
  485.  
  486. If we also had to swap floats, longs, Strings, Sets, and FileSystems, we'd get
  487. pretty tired of coding lines that look almost identical except for the type.
  488. Mindless repetition is an ideal job for a computer, hence a function template:
  489.  
  490.     template<class T>
  491.     void swap(T& x, T& y)
  492.     {
  493.       T tmp = x;
  494.       x = y;
  495.       y = tmp;
  496.     }
  497.  
  498. Every time we used "swap()" with a given pair of types, the compiler will go to
  499. the above definition and will create yet another "template function" as an
  500. instantiation of the above.  E.g.,
  501.  
  502.     main()
  503.     {
  504.       int    i,j;  /*...*/  swap(i,j);  //instantiates a swap for "int"
  505.       float  a,b;  /*...*/  swap(a,b);  //instantiates a swap for "float"
  506.       char   c,d;  /*...*/  swap(c,d);  //instantiates a swap for "char"
  507.       String s,t;  /*...*/  swap(s,t);  //instantiates a swap for "String"
  508.     }
  509.  
  510. (note: a "template function" is the instantiation of a "function template").
  511.  
  512. ==============================================================================
  513.  
  514. Q128: What's the syntax / semantics for a "class template"?
  515.  
  516. Consider a container class of that acts like an array of integers:
  517.  
  518.     //this would go into a header file such as "Array.h"
  519.     class Array {
  520.     public:
  521.       Array(int len=10)                  : len_(len), data_(new int[len]){}
  522.      ~Array()                            { delete [] data_; }
  523.       int len() const                    { return len_;     }
  524.       const int& operator[](int i) const { data_[check(i)]; }
  525.             int& operator[](int i)       { data_[check(i)]; }
  526.       Array(const Array&);
  527.       Array& operator= (const Array&);
  528.     private:
  529.       int  len_;
  530.       int* data_;
  531.       int  check(int i) const
  532.         { if (i < 0 || i >= len_) throw BoundsViol("Array", i, len_);
  533.           return i; }
  534.     };
  535.  
  536. Just as with "swap()" above, repeating the above over and over for Array of
  537. float, of char, of String, of Array-of-String, etc, will become tedious.
  538.  
  539.     //this would go into a header file such as "Array.h"
  540.     template<class T>
  541.     class Array {
  542.     public:
  543.       Array(int len=10)                : len_(len), data_(new T[len]) { }
  544.      ~Array()                          { delete [] data_; }
  545.       int len() const                  { return len_;     }
  546.       const T& operator[](int i) const { data_[check(i)]; }
  547.             T& operator[](int i)       { data_[check(i)]; }
  548.       Array(const Array<T>&);
  549.       Array& operator= (const Array<T>&);
  550.     private:
  551.       int len_;
  552.       T*  data_;
  553.       int check(int i) const
  554.         { if (i < 0 || i >= len_) throw BoundsViol("Array", i, len_);
  555.           return i; }
  556.     };
  557.  
  558. Unlike template functions, template classes (instantiations of class templates)
  559. need to be explicit about the parameters over which they are instantiating:
  560.  
  561.     main()
  562.     {
  563.       Array<int>           ai;
  564.       Array<float>         af;
  565.       Array<char*>         ac;
  566.       Array<String>        as;
  567.       Array< Array<int> >  aai;
  568.     }              // ^^^-- note the space; do NOT use "Array<Array<int>>"
  569.                    //       (the compiler sees ">>" as a single token).
  570.  
  571. ==============================================================================
  572.  
  573. Q129: What is a "parameterized type"?
  574.  
  575. Another way to say, "class templates."
  576.  
  577. A parameterized type is a type that is parameterized over another type or some
  578. value.  List<int> is a type ("List") parameterized over another type ("int").
  579.  
  580. ==============================================================================
  581.  
  582. Q130: What is "genericity"?
  583.  
  584. Yet another way to say, "class templates."
  585.  
  586. Not to be confused with "generality" (which just means avoiding solutions which
  587. are overly specific), "genericity" means class templates.
  588.  
  589. ==============================================================================
  590. SECTION 20: Libraries
  591. ==============================================================================
  592.  
  593. Q131: Where can I get a copy of "STL"?
  594.  
  595. "STL" is the "Standard Templates Library".  You can get a copy from:
  596.  
  597. An STL site:
  598.     ftp://ftp.cs.rpi.edu/pub/stl
  599.  
  600. STL HP official site:
  601.     ftp://butler.hpl.hp.com/stl/
  602.  
  603. Mirror site in Europe:
  604.     http://www.maths.warwick.ac.uk/ftp/mirrors/c++/stl/
  605.  
  606. STL code alternate:
  607.     ftp://ftp.cs.rpi.edu/stl
  608.  
  609. STL code + examples:
  610.     http://www.cs.rpi.edu/~musser/stl.html
  611.  
  612. STL hacks for GCC-2.6.3 are part of the GNU libg++ package 2.6.2.1 or later
  613. (and they may be in an earlier version as well).  Thanks to Mike Lindner.
  614.  
  615. ==============================================================================
  616.  
  617. Q132: Where can I get help on how to use STL?
  618.  
  619. Kenny Zalewski's STL guide:
  620.     http://www.cs.rpi.edu/projects/STL/htdocs/stl-new.html
  621.  
  622. Dave Musser's STL guide:
  623.     http://www.cs.rpi.edu/~musser/stl.html
  624.  
  625. Mumit's STL Newbie's guide:
  626.     http://www.xraylith.wisc.edu/~khan/software/stl/STL.newbie.html
  627.  
  628. ==============================================================================
  629.  
  630. Q133: Where can I ftp the code that accompanies "Numerical Recipes"?
  631.  
  632. This software is sold and there for it would be illegal to provide it on the
  633. net.  However, it's only about $30.
  634.  
  635. ==============================================================================
  636.  
  637. Q134: Why is my executable so large?
  638.  
  639. Many people are surprised by how big executables are, especially if the source
  640. code is trivial.  For example, a simple "hello world" program can generate an
  641. executable that is larger than most people expect (40+K bytes).
  642.  
  643. One reason executables can be large is that portions of the C++ runtime
  644. library gets linked with your program. How much gets linked in depends on how
  645. much of it you are using, and on how the implementor split up the library into
  646. pieces.  For example, the iostream library is quite large, and consists of
  647. numerous classes and virtual functions. Using any part of it might pull in
  648. nearly all of the iostream code as a result of the interdependencies.
  649.  
  650. You might be able to make your program smaller by using a dynamically-linked
  651. version of the library instead of the static version.
  652.  
  653. You have to consult your compiler manuals or the vendor's technical support
  654. for a more detailed answer.
  655.  
  656. ==============================================================================
  657. SECTION 21: Nuances of particular implementations
  658. ==============================================================================
  659.  
  660. Q135: GNU C++ (g++) produces big executables for tiny programs; Why?
  661.  
  662. libg++ (the library used by g++) was probably compiled with debug info (-g).
  663. On some machines, recompiling libg++ without debugging can save lots of disk
  664. space (~1 Meg; the down-side: you'll be unable to trace into libg++ calls).
  665. Merely "strip"ping the executable doesn't reclaim as much as recompiling
  666. without -g followed by subsequent "strip"ping the resultant "a.out"s.
  667.  
  668. Use "size a.out" to see how big the program code and data segments really are,
  669. rather than "ls -s a.out" which includes the symbol table.
  670.  
  671. ==============================================================================
  672.  
  673. Q136: Is there a yacc-able C++ grammar?
  674.  
  675. Jim Roskind is the author of a yacc grammar for C++. It's roughly compatible
  676. with the portion of the language implemented by USL cfront 2.0 (no templates,
  677. no exceptions, no run-time-type-identification).  Jim's grammar deviates from
  678. C++ in a couple of minor-but-subtle ways.
  679.  
  680. The grammar can be accessed on-line as follows:
  681.  * ftp://ics.uci.edu/gnu/c++grammar2.0.tar.Z
  682.    (ics.uci.edu is IP 128.195.1.1)
  683.  * ftp://mach1.npac.syr.edu/pub/C++/c++grammar2.0.tar.Z
  684.    (mach1.npac.syr.edu is IP 128.230.7.14)
  685.  
  686. [NOTE: I was told that these ftp addresses are no longer valid.  Would someone
  687. please either confirm or deny this assertion, and would someone please let me
  688. know of an alternate address.  Thanks; Marshall Cline]
  689.  
  690. ==============================================================================
  691.  
  692. Q137: What is C++ 1.2?  2.0?  2.1?  3.0?
  693.  
  694. These are not versions of the language, but rather versions of cfront, which
  695. was the original C++ translator implemented by AT&T.  It has become generally
  696. accepted to use these version numbers as if they were versions of the language
  697. itself.
  698.  
  699. *VERY* roughly speaking, these are the major features:
  700.  * 2.0 includes multiple/virtual inheritance and pure virtual functions.
  701.  * 2.1 includes semi-nested classes and "delete [] ptr_to_array."
  702.  * 3.0 includes fully-nested classes, templates and "i++" vs "++i."
  703.  * 4.0 will include exceptions.
  704.  
  705. ==============================================================================
  706.  
  707. Q138: If name mangling was standardized, could I link code compiled with
  708.    compilers from different compiler vendors?
  709.  
  710. Short answer: Probably not.
  711.  
  712. In other words, some people would like to see name mangling standards
  713. incorporated into the proposed C++ ANSI standards in an attempt to avoiding
  714. having to purchase different versions of class libraries for different
  715. compiler vendors.  However name mangling differences are one of the smallest
  716. differences between implementations, even on the same platform.  Here is a
  717. partial list of other differences:
  718.  
  719. 1) Number and type of hidden arguments to member functions.
  720.    1a) is 'this' handled specially?
  721.    1b) where is the return-by-value pointer passed?
  722. 2) Assuming a vtable is used:
  723.    2a) what is its contents and layout?
  724.    2b) where/how is the adjustment to 'this' made for multiple inheritance?
  725. 3) How are classes laid out, including:
  726.    3a) location of base classes?
  727.    3b) handling of virtual base classes?
  728.    3c) location of vtable pointers, if vtables are used?
  729. 4) Calling convention for functions, including:
  730.    4a) does caller or callee adjust the stack?
  731.    4b) where are the actual parameters placed?
  732.    4c) in what order are the actual parameters passed?
  733.    4d) how are registers saved?
  734.    4e) where does the return value go?
  735.    4f) special rules for passing or returning structs or doubles?
  736.    4g) special rules for saving registers when calling leaf functions?
  737. 5) How is the run-time-type-identification laid out?
  738. 6) How does the runtime exception handling system know which local objects
  739.    need to be destructed during an exception throw?
  740.  
  741. ==============================================================================
  742. SECTION 22: Miscellaneous technical and environmental issues
  743. ==============================================================================
  744. SUBSECTION 22A: Miscellaneous technical issues:
  745. ==============================================================================
  746.  
  747. Q139: Why are classes with static data members getting linker errors?
  748.  
  749. Static data members must be explicitly defined in exactly one module.  E.g.,
  750.  
  751.     class Fred {
  752.     public:
  753.       //...
  754.     private:
  755.       static int i_;  //declares static data member "Fred::i_"
  756.       //...
  757.     };
  758.  
  759. The linker will holler at you ("Fred::i_ is not defined") unless you define (as
  760. opposed to declare) "Fred::i_" in (exactly) one of your source files:
  761.  
  762.     int Fred::i_ = some_expression_evaluating_to_an_int;
  763. or:
  764.     int Fred::i_;
  765.  
  766. The usual place to define static data members of class "Fred" is file "Fred.C"
  767. (or "Fred.cpp", etc; whatever filename extension you use).
  768.  
  769. ==============================================================================
  770.  
  771. Q140: What's the difference between the keywords struct and class?
  772.  
  773. The members and base classes of a struct are public by default, while in class,
  774. they default to private.  Note: you should make your base classes EXPLICITLY
  775. public, private, or protected, rather than relying on the defaults.
  776.  
  777. "struct" and "class" are otherwise functionally equivalent.
  778.  
  779. ==============================================================================
  780.  
  781. Q141: Why can't I overload a function by its return type?
  782.  
  783. If you declare both "char f()" and "float f()", the compiler gives you an error
  784. message, since calling simply "f()" would be ambiguous.
  785.  
  786. ==============================================================================
  787.  
  788. Q142: What is "persistence"?  What is a "persistent object"?
  789.  
  790. A persistent object can live after the program which created it has stopped.
  791. Persistent objects can even outlive different versions of the creating program,
  792. can outlive the disk system, the operating system, or even the hardware on
  793. which the OS was running when they were created.
  794.  
  795. The challenge with persistent objects is to effectively store their method code
  796. out on secondary storage along with their data bits (and the data bits and
  797. method code of all member objects, and of all their member objects and base
  798. classes, etc).  This is non-trivial when you have to do it yourself.  In C++,
  799. you have to do it yourself.  C++/OO databases can help hide the mechanism for
  800. all this.
  801.  
  802. ==============================================================================
  803.  
  804. Q143: Why is floating point so inaccurate?  Why doesn't this print 0.43?
  805.  
  806.     #include<iostream.h> 
  807.  
  808.     main()
  809.     {
  810.       float a = 1000.43;
  811.       float b = 1000.0;
  812.       cout << a - b << '\n';
  813.     } 
  814.  
  815. (note, on one C++ implementation, this prints 0.429993) 
  816.  
  817. Disclaimer: Frustration with rounding/truncation/approximation isn't really a
  818. C++ issue.  It's a computer science issue.  However, people keep asking about
  819. it on comp.lang.c++, so here's a nominal answer.
  820.  
  821. Answer: Floating point is an approximation.  The IEEE standard for 32 bit
  822. float supports 1 bit of sign, 8 bits of exponent, and 23 bits of mantissa.
  823. Since a normalized binary-point mantissa always has the form 1.xxxxx... the
  824. leading 1 is dropped and you get effectively 24 bits of mantissa.  The number
  825. 1000.43 (and many, many others) is not exactly representable in float or
  826. double format.  1000.43 is actually represented as the following bitpattern
  827. (the 's' shows the position of the sign bit, the 'e's show the positions of
  828. the exponent bits, and the 'm's show the positions of the mantissa bits):
  829.  
  830.     seeeeeeeemmmmmmmmmmmmmmmmmmmmmmm 
  831.     01000100011110100001101110000101 
  832.  
  833. The shifted mantissa is 1111101000.01101110000101 or 1000 + 7045/16384.  The
  834. fractional part is 0.429992675781.  With 24 bits of mantissa you only get
  835. about 1 part in 16M of precision for float.  The 'double' type provides more
  836. precision (53 bits of mantissa).
  837.  
  838. ==============================================================================
  839. SUBSECTION 22B: Miscellaneous environmental issues:
  840. ==============================================================================
  841.  
  842. Q144: Is there a TeX or LaTeX macro that fixes the spacing on "C++"?
  843.  
  844. Yes, here are three (the first prevents line breaks between the "C" and "++"):
  845.  
  846. \def\CC{{C\nolinebreak[4]\hspace{-.05em}\raisebox{.4ex}{\tiny\bf ++}}}
  847.  
  848. \def\CC{C\raise.22ex\hbox{{\footnotesize +}}\raise.22ex\hbox{\footnotesize +}}
  849.  
  850. \def\CC{{C\hspace{-.05em}\raisebox{.4ex}{\tiny\bf ++}}}
  851.  
  852. ==============================================================================
  853.  
  854. Q145: Where can I access C++2LaTeX, a LaTeX pretty printer for C++ source?
  855.  
  856. ftp://ftp.german.eu.net/pub/packages/TeX/support/pretty/C++2LaTeX-3.02.tar.gz
  857.  
  858. ==============================================================================
  859.  
  860. Q146: Where can I access "tgrind," a pretty printer for C++/C/etc source?
  861.  
  862. "tgrind" reads a C++ source file, and spits out something that looks pretty on
  863. most Unix printers.  It usually comes with the public distribution of TeX and
  864. LaTeX; look in the directory: "...tex82/contrib/van/tgrind".  A more up-to-date
  865. version of tgrind by Jerry Leichter can be found on: venus.ycc.yale.edu in
  866. [.TGRIND].
  867.  
  868. ==============================================================================
  869.  
  870. Q147: Is there a C++-mode for GNU emacs?  If so, where can I get it?
  871.  
  872. Yes, there is a C++-mode for GNU emacs.
  873.  
  874. The latest and greatest version of C++-mode (and c-mode) is implemented in the
  875. file cc-mode.el.  It is an extension of Detlef & Clamen's version.
  876. A version is included with emacs.  Newer version are availiable from
  877. the elisp archives.
  878.  
  879. ==============================================================================
  880.  
  881. Q148: Where can I get OS-specific FAQs answered (e.g.,BC++,DOS,Windows,etc)?
  882.  
  883. See one of the following:
  884.  * comp.os.msdos.programmer
  885.  * comp.windows.ms.programmer
  886.  * comp.unix.programmer
  887.  
  888. [If anyone has an email address for a BC++, VC++, or Semantic C++ bug list
  889. and/or discussion mailing list, please let me know how to subscribe, and I'll
  890. mention it here].
  891.  
  892. ==============================================================================
  893.  
  894. Q149: Why does my DOS C++ program says "Sorry: floating point code not
  895.    linked"?
  896.  
  897. The compiler attempts to save space in the executable by not including the
  898. float-to-string format conversion routines unless they are necessary, but
  899. sometimes it guesses wrong, and gives you the above error message.  You can fix
  900. this by (1) using <iostream.h> instead of <stdio.h>, or (2) by including the
  901. following function somewhere in your compilation (but don't call it!):
  902.  
  903.     static void dummyfloat(float *x) { float y; dummyfloat(&y); }
  904.  
  905. See FAQ on stream I/O for more reasons to use <iostream.h> vs <stdio.h>.
  906.  
  907. ==============================================================================
  908.  
  909. Q150: Why does my BC++ Windows app crash when I'm not running the BC45 IDE?
  910.  
  911. If you're using BC++ for a Windows app, and it works ok as long as you have the
  912. BC45 IDE running, but when the BC45 IDE is shut down you get an exception
  913. during the creation of a window, then add the following line of code to the
  914. InitMainWindow() method of your application ("YourApp::InitMainWindow()"):
  915.  
  916.     EnableBWCC(TRUE);
  917.  
  918. ==============================================================================
  919.  
  920. --
  921. Paradigm Shift, Inc. / P.O. Box 5108 / Potsdam, NY  13676
  922. Technology consulting services
  923. cline@parashift.com / Voice: 315-353-6100 / FAX: 315-353-6110
  924.